#include "Protocol.hpp"
#include "Sock.hpp"
#include <pthread.h>

static void Usage(string proc)
{
    cout << "Usage:" << proc << "port" << endl;
    exit(1);
}

void *HandlerRequest(void *args)
{
    int sock = *(int *)args;
    delete (int *)args;

    pthread_detach(pthread_self());

    // vesion1 原生方法，没有明显的序列化和反序列化
    //业务逻辑
    // 1、读取请求
    request_t req;
    //从sock里读取sizeof(req)个字节写入req
    ssize_t s = read(sock, &req, sizeof(req));
    if (s == sizeof(req))
    {
        // 2、分析请求&&计算结果
        //读取到了完整的请求
        response_t resp = {0, 0};
        switch (req.op)
        {
        case '+':
            resp.result = req.x + req.y;
            break;
        case '-':
            resp.result = req.x - req.y;
            break;
        case '*':
            resp.result = req.x * req.y;
            break;
        case '/':
            if (req.y == 0)
            {
                resp.code = -1; //除0
            }
            else
            {
                resp.result = req.x / req.y;
            }
            break;
        case '%':
            if (req.y == 0)
            {
                resp.code = -2; //模0
            }
            else
            {
                resp.result = req.x / req.y;
            }
            break;
        default:
            resp.code = -3; //请求方法异常
            break;
        }
        cout << "request:" << req.x << req.op << req.y << endl;
        // 3、返回读取结果
        //从resp里读取sizeof(resp)个字节写入sock
        write(sock, &resp, sizeof(resp));

        cout << "服务结束" << endl;
    }

    // 4、关闭链接
    close(sock);
}

//./CalServer port
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
    }
    uint16_t port = atoi(argv[1]);

    int listen_sock = Sock::Socket();
    Sock::Bind(listen_sock, port);
    Sock::Listen(listen_sock);

    for (;;)
    {
        int sock = Sock::Accept(listen_sock);
        if (sock >= 0)
        {
            cout << "get a new client..." << endl;
            int *pram = new int(sock);
            pthread_t tid;
            pthread_create(&tid, nullptr, HandlerRequest, pram);
        }
    }

    return 0;
}